//
// Created by Dou on 2018/2/1.
//
#include "inc/fmod.hpp"
#include "com_dou_sample_fmod_demo_project_VoiceTool.h"
#include <android/log.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

#define TAG "Voice Tool"

// 变声的类型
#define TYPE_NORMAL 0
#define TYPE_LUOLI 1
#define TYPE_DASHU 2
#define TYPE_JINGSONG 3
#define TYPE_GAOGUAI 4
#define TYPE_KONGLING 5

// 日志输出函数
#define LOGD(FORMAT, ...) __android_log_print(ANDROID_LOG_DEBUG, TAG, FORMAT, __VA_ARGS__);
#define LOGE(FORMAT, ...) __android_log_print(ANDROID_LOG_ERROR, TAG, FORMAT, __VA_ARGS__);

using namespace FMOD;

extern "C" {

JNIEXPORT void JNICALL Java_com_dou_sample_fmod_1demo_1project_VoiceTool_changeVoice
        (JNIEnv *env, jclass obj, jstring path_, jint type_) {
    const char* path = env->GetStringUTFChars(path_, NULL);
    static System* system;
    Channel* channel;
    DSP* dsp;
    Sound* sound;

    bool isPlaying = true;
    float frequency;

    if (system != NULL){
        system->close();
        system->release();

        system = NULL;
    }

    // fmod 初始化
    System_Create(&system);
    // 指定最大声轨数等参数
    system->init(32, FMOD_INIT_NORMAL, NULL);

    //创建声音对象
    system->createSound(path, FMOD_DEFAULT, NULL, &sound);

    switch (type_) {

        case TYPE_NORMAL:
            // 原声播放，指定音轨为0，最后update的时候才会播放
            system->playSound(sound, 0, false, &channel);
            LOGD("%s", "normal")
            break;

        case TYPE_LUOLI:
            // 创建一个数字信号DSP(数字信号处理)处理声音
            // dsp的原理是通过两个参数改变声音：振幅和频率
            system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT, &dsp);
            // 设置参数，提高频率
            dsp->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH, 2.5);
            system->playSound(sound, 0, false, &channel);
            channel->addDSP(0, dsp);
            LOGD("%s", "luo li");
            break;

        case TYPE_DASHU:
            system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT, &dsp);
            dsp->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH, 0.8);
            system->playSound(sound, 0, false, &channel);
            channel->addDSP(0, dsp);
            LOGD("%s", "da shu")
            break;

        case TYPE_JINGSONG:
            system->createDSPByType(FMOD_DSP_TYPE_TREMOLO, &dsp);
            dsp->setParameterFloat(FMOD_DSP_TREMOLO_SKEW, 0.5);
            system->playSound(sound, 0, false, &channel);
            channel->addDSP(0, dsp);
            LOGD("%s", "jing song");
            break;
        case TYPE_GAOGUAI:
            // 提高说话的频率
            system->playSound(sound, 0, false, &channel);
            channel->getFrequency(&frequency);
            frequency = frequency * 1.6;
            channel->setFrequency(frequency);
            LOGD("%s", "gao guai");
            break;
        case TYPE_KONGLING:
            system->createDSPByType(FMOD_DSP_TYPE_ECHO, &dsp);
            dsp->setParameterInt(FMOD_DSP_ECHO_DELAY, 300);
            dsp->setParameterInt(FMOD_DSP_ECHO_FEEDBACK, 20);
            system->playSound(sound, 0, false, &channel);
            channel->addDSP(0, dsp);
            LOGD("%s", "kong ling");
            break;
        default:
            break;
    }

    // update的时候才会播放音乐
    system->update();

    // 每隔一秒去判断是否正在播放
    while (isPlaying){
        channel->isPlaying(&isPlaying);
        usleep(1 * 1000 * 1000);
    }

    sound->release();
    system->close();
    system->release();

    env->ReleaseStringUTFChars(path_, path);
} ;

}